package test.example

import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test
import org.mockito.Mockito.`when`
import org.mockito.Mockito.mock
import org.mockito.Mockito.times
import org.mockito.Mockito.verify

import test.util.Log

interface Dog {
    fun eat(food: String): Boolean
}

class Person(val name: String) {
    fun feedDog(dog: Dog, food: String): Boolean {
        Log.d(TAG, "Person $name feed dog with food $food")
        return dog.eat(food)
    }

    companion object {
        private const val TAG: String = "Person"
    }
}

class ExampleMockTest {
    @Test
    fun dogIsAlwaysHungry() {
        val dog = mock(Dog::class.java)
        `when`(dog.eat("meat")).thenReturn(false)

        val person = Person("Bob")
        val count = 10
        for (i in 1..count) {
            val isFull = person.feedDog(dog, "meat")
            assertFalse(isFull)
        }

        verify(dog, times(count)).eat("meat")
        verify(dog, times(0)).eat("egg")
    }

    @Test
    fun dogIsFullWithSpecificFood() {
        val dog = mock(Dog::class.java)
        `when`(dog.eat("meat1")).thenReturn(false)
        `when`(dog.eat("meat2")).thenReturn(false)
        `when`(dog.eat("meat3")).thenReturn(true)

        val person = Person("Bob")
        var isFull = person.feedDog(dog, "meat1")
        assertFalse(isFull)

        isFull = person.feedDog(dog, "meat2")
        assertFalse(isFull)

        isFull = person.feedDog(dog, "meat3")
        assertTrue(isFull)

        verify(dog, times(1)).eat("meat1")
        verify(dog, times(1)).eat("meat2")
        verify(dog, times(1)).eat("meat3")
        verify(dog, times(0)).eat("egg")
    }
}
